home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_se / system_tools.e < prev    next >
Text File  |  1998-12-22  |  17KB  |  648 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class SYSTEM_TOOLS
  17.    --
  18.    -- Singleton object to handle system dependant information.
  19.    -- This singleton is shared via the GLOBALS.`system_tools' once function.
  20.    --
  21.    -- Only this object is supposed to handle contents of the `SmallEiffel' 
  22.    -- system environment variable.
  23.    --
  24.    -- You may also want to customize this class in order to support a 
  25.    -- new operating system (please let us know).
  26.    --
  27.  
  28. inherit GLOBALS;
  29.  
  30. creation make
  31.  
  32. feature {NONE} -- Currently handled system List :
  33.    
  34.    amiga_system:       STRING is "Amiga";
  35.    beos_system:        STRING is "BeOS";
  36.    dos_system:         STRING is "DOS";
  37.    macintosh_system:   STRING is "Macintosh";
  38.    os2_system:         STRING is "OS2";
  39.    unix_system:        STRING is "UNIX";
  40.    vms_system:         STRING is "VMS";
  41.    windows_system:     STRING is "Windows";
  42.  
  43. feature {NONE}
  44.  
  45.    system_list: ARRAY[STRING] is
  46.       once
  47.      Result := << amiga_system,
  48.               beos_system, 
  49.               dos_system,
  50.               macintosh_system, 
  51.               os2_system, 
  52.               unix_system,
  53.               vms_system, 
  54.               windows_system
  55.               >>;
  56.       end;
  57.  
  58. feature {NONE}
  59.  
  60.    system_name: STRING;
  61.  
  62.    sys_directory: STRING;
  63.      -- The SmallEiffel/sys directory computed with the value of
  64.      -- the environment variable `SmallEiffel'.
  65.      -- For example, under UNIX: "/usr/lib/SmallEiffel/sys/"
  66.  
  67.    bin_directory: STRING;
  68.      -- For example, under UNIX: "/usr/lib/SmallEiffel/bin/"
  69.    
  70. feature {NONE}
  71.    
  72.    make is
  73.       local
  74.      system_se_path: STRING;
  75.      i: INTEGER;
  76.       do
  77.      system_se_path := get_environment_variable(fz_se);
  78.      if system_se_path = Void then
  79.         system_se_path := fz_se.twin;
  80.         system_se_path.to_upper;
  81.         system_se_path := get_environment_variable(system_se_path);
  82.         if system_se_path = Void then
  83.            echo.put_string(
  84.                   "System environment variable %"SmallEiffel%" not set.%N%
  85.                   %Trying default value: %"");
  86.            system_se_path := "/usr/lib/SmallEiffel/sys/system.se";
  87.            echo.put_string(system_se_path);
  88.            echo.put_string(fz_03);
  89.         end;
  90.      end;
  91.      if system_se_path.has_suffix(fz_system_se) then
  92.         echo.sfr_connect(tmp_file_read,system_se_path);
  93.      else
  94.         echo.put_string(
  95.                "You should update the value of the %"SmallEiffel%" %
  96.                %system environment variable.%N%
  97.                %Since release -0.79, the %"SmallEiffel%" system %
  98.                %environment variable must be the absolute path of %
  99.                %the %"system.se%" file.%N%
  100.                %For example %"/usr/lib/SmallEiffel/sys/system.se%" %
  101.                %under Unix like system.%N");
  102.         if system_se_path.has('/') then
  103.            echo.put_string("%"Hope this is a Unix like system.%N");
  104.            tmp_path.copy(system_se_path);
  105.            tmp_path.set_last('/');
  106.            tmp_path.append(fz_sys);
  107.            tmp_path.extend('/');
  108.            tmp_path.append(fz_system_se);
  109.            echo.sfr_connect(tmp_file_read,tmp_path);
  110.         end;
  111.         if not tmp_file_read.is_connected then
  112.            if system_se_path.has('\') then
  113.           echo.put_string("%"Hope this is a DOS or Windows like system.%N");
  114.           tmp_path.copy(system_se_path);
  115.           tmp_path.set_last('\');
  116.           tmp_path.append(fz_sys);
  117.           tmp_path.extend('\');
  118.           tmp_path.append(fz_system_se);
  119.           echo.sfr_connect(tmp_file_read,tmp_path);
  120.            end;
  121.         end;
  122.         if not tmp_file_read.is_connected then
  123.            if system_se_path.has(':') then
  124.           echo.put_string("%"Hope this is a Macintosh like system.%N");
  125.           tmp_path.copy(system_se_path);
  126.           tmp_path.set_last(':');
  127.           tmp_path.append(fz_sys);
  128.           tmp_path.extend(':');
  129.           tmp_path.append(fz_system_se);
  130.           echo.sfr_connect(tmp_file_read,tmp_path);
  131.            end;
  132.         end;
  133.         if not tmp_file_read.is_connected then
  134.            if system_se_path.has(']') then
  135.           echo.put_string("%"Hope this is a VMS system.%N");
  136.           tmp_path.copy(system_se_path);
  137.           tmp_path.set_last(']');
  138.           tmp_path.remove_last(1);
  139.           tmp_path.extend('.');
  140.           tmp_path.append(fz_sys);
  141.           tmp_path.extend(']');
  142.           tmp_path.append(fz_system_se);
  143.           echo.sfr_connect(tmp_file_read,tmp_path);
  144.            end;
  145.         end;
  146.         if not tmp_file_read.is_connected then
  147.            echo.put_string("%"Last chance.%N");
  148.            tmp_path.copy(system_se_path);
  149.            tmp_path.append(fz_system_se);
  150.            echo.sfr_connect(tmp_file_read,tmp_path);
  151.         end;
  152.      end;
  153.      if not tmp_file_read.is_connected then
  154.         echo.w_put_string(
  155.                "Unable to find file %"system.se%".%N%
  156.                %Please, set the environment variable %"SmallEiffel%" %
  157.            %with the appropriate absolute path to this file.%N%
  158.            %Example for Unix: %"/usr/lib/SmallEiffel/sys/system.se%"%N%
  159.                %Example for DOS/Windows: %"C:\SmallEiffel\sys\system.se%"%N");
  160.         die_with_code(exit_failure_code);
  161.      end;
  162.      tmp_file_read.read_line;
  163.      system_name := tmp_file_read.last_string;
  164.      i := system_list.index_of(system_name);
  165.      if i > system_list.upper then
  166.         echo.w_put_string("Unknown system name in file%N%"");
  167.         echo.w_put_string(tmp_file_read.path);
  168.         echo.w_put_string("%".%NCurrently handled system names :%N");
  169.         from
  170.            i := 1;
  171.         until
  172.            i > system_list.upper
  173.         loop
  174.            echo.w_put_string(system_list.item(i));
  175.            echo.w_put_character('%N');
  176.            i := i + 1;
  177.         end;
  178.         die_with_code(exit_failure_code);
  179.      else
  180.         system_name := system_list.item(i);
  181.         echo.put_string("System is %"");
  182.         echo.put_string(system_name);
  183.         echo.put_string(fz_b0);
  184.      end;
  185.      sys_directory := tmp_file_read.path.twin;
  186.      sys_directory.remove_suffix(fz_system_se);
  187.      tmp_file_read.disconnect;
  188.      bin_directory := sys_directory.twin;
  189.      parent_directory(bin_directory);
  190.      add_directory(bin_directory,fz_bin);
  191.       end;
  192.  
  193. feature {COMPILE}
  194.  
  195.    compile_to_c_in(command: STRING) is
  196.      -- Append the system command call
  197.       do
  198.      if windows_system /= system_name then
  199.         command.append(bin_directory);
  200.          end;
  201.      command.append(us_compile_to_c);
  202.      command.append(x_suffix);
  203.       end;
  204.  
  205. feature {COMPILE}
  206.  
  207.    clean_in(command: STRING) is
  208.       do
  209.      if windows_system /= system_name then
  210.         command.append(bin_directory);
  211.      end;
  212.      command.append(fz_clean);
  213.      command.append(x_suffix);
  214.       end;
  215.  
  216. feature {C_PRETTY_PRINTER}
  217.  
  218.    first_line_of_sys_file(name: STRING): STRING is
  219.      -- Create a new STRING which is the contents of the first 
  220.      -- line of the corresponding SmallEiffel/sys/ directory.
  221.       do
  222.      tmp_path.copy(sys_directory);
  223.      tmp_path.append(name);
  224.      tmp_path.append(system_name);
  225.      echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  226.      tmp_file_read.read_line;
  227.      Result := tmp_file_read.last_string.twin;
  228.      tmp_file_read.disconnect;
  229.       end;
  230.  
  231. feature {C_PRETTY_PRINTER}
  232.  
  233.    sys_runtime(name: STRING; suffix: CHARACTER) is
  234.      -- Prepare `tmp_file_read' to access the corresponding file 
  235.      -- in the SmallEiffel/sys/runtime directory.
  236.       require
  237.      name /= Void;
  238.      suffix = 'c' or suffix = 'h'
  239.       do
  240.      tmp_path.copy(sys_directory);
  241.      add_directory(tmp_path,fz_runtime);
  242.      tmp_path.append(name);
  243.      tmp_path.extend('.');
  244.      tmp_path.extend(suffix);
  245.      echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  246.       ensure
  247.      tmp_file_read.is_connected
  248.       end;
  249.    
  250. feature {COMPILE,CLEAN}
  251.  
  252.    remove_make_script: STRING is
  253.      -- Compute the corresponding make file script and remove
  254.      -- the old one if any.
  255.       do
  256.      Result := path_h;
  257.      Result.remove_suffix(h_suffix);
  258.      Result.append(make_suffix);
  259.          echo.file_removing(Result);
  260.       end;
  261.  
  262. feature {C_PRETTY_PRINTER}
  263.  
  264.    path_h: STRING is
  265.      -- Create a new STRING which is the name of the
  266.      -- main *.h file.
  267.       do
  268.      Result := run_control.root_class.twin;
  269.      Result.to_lower;
  270.      if dos_system = system_name then
  271.         from
  272.         until
  273.            Result.count <= 4
  274.         loop
  275.            Result.remove_last(1);
  276.         end;
  277.      end;
  278.      Result.append(h_suffix);
  279.       end;
  280.  
  281. feature {SMALL_EIFFEL}
  282.  
  283.    read_loading_path_in(lp: ARRAY[STRING]) is
  284.       do
  285.      loading_path_add(lp,fz_loadpath_se,1);
  286.      tmp_path.copy(sys_directory);
  287.      tmp_path.append("loadpath.");
  288.      tmp_path.append(system_name);
  289.      loading_path_add(lp,tmp_path,1);
  290.       end;
  291.  
  292. feature {NONE}
  293.  
  294.    fz_loadpath_se: STRING is "loadpath.se";
  295.  
  296.    loading_path_add(lp: ARRAY[STRING]; path: STRING; level: INTEGER) is
  297.       local
  298.      file: STD_FILE_READ;
  299.      line: STRING;
  300.       do
  301.      if level > 5 or else lp.count > 1024 then
  302.         echo.w_put_string(
  303.                "Eiffel source loading path too long or infinite %
  304.            %loadpath.se includes.%N");
  305.         !!line.make(1024);
  306.         append_lp_in(line,lp);
  307.         echo.w_put_string(line);
  308.         die_with_code(exit_failure_code);
  309.      end;
  310.      !!file.make;
  311.      echo.sfr_connect(file,path);
  312.      if file.is_connected then
  313.         from
  314.            echo.put_string("Append contents of  %"");
  315.            echo.put_string(path);
  316.            echo.put_string("%" to loading path.%N");
  317.         until
  318.            file.end_of_input
  319.         loop
  320.            file.read_line;
  321.            line := file.last_string.twin;
  322.            if line.has_suffix(fz_loadpath_se) then
  323.           loading_path_add(lp,line,level + 1);
  324.            elseif not line.empty then
  325.           lp.add_last(line);
  326.            end;
  327.         end;
  328.         file.disconnect;
  329.      end;
  330.       end;
  331.  
  332. feature {SMALL_EIFFEL}
  333.    
  334.    append_lp_in(str: STRING; lp: ARRAY[STRING]) is
  335.       local      
  336.      i: INTEGER;
  337.      sed: STRING;
  338.       do
  339.      str.append("%NLoading path is:%N[%N");
  340.      from  
  341.         i := lp.lower;
  342.      until
  343.         i > lp.upper 
  344.      loop
  345.         str.extend(' ');
  346.         str.extend('%"');
  347.         str.append(lp.item(i));
  348.         str.extend('%"');
  349.         str.extend('%N');
  350.         i := i + 1;
  351.      end;
  352.      str.append("]%NEnvironment Variable %"SmallEiffel%" is:%N");
  353.      sed := get_environment_variable(fz_se);
  354.      if sed = Void then
  355.         str.append("not set.%N");
  356.      else
  357.         str.append(" %"");
  358.         str.append(sed);
  359.         str.append("%".%N");
  360.      end;
  361.       end;
  362.  
  363. feature {GC_HANDLER}
  364.  
  365.    put_mark_stack_and_registers is
  366.      -- Add customized assembly code to mark registers.
  367.       local
  368.      architecture: STRING;
  369.       do
  370.      tmp_path.copy(sys_directory);
  371.      tmp_path.append(fz_gc);
  372.      echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  373.      architecture := echo.read_word_in(tmp_file_read);
  374.      tmp_file_read.disconnect;
  375.      if us_none.is_equal(architecture) then
  376.         eh.append(
  377.            "Assembly Code for Garbage Collector not selected in %"");
  378.         eh.append(tmp_path);
  379.         eh.append(
  380.                "%". Default generic (hazardous) C code is provided.");
  381.         eh.print_as_warning;
  382.         architecture := "generic.c";
  383.      end;
  384.      tmp_path.copy(sys_directory);
  385.      add_directory(tmp_path,fz_gc_lib);
  386.      tmp_path.append(architecture);
  387.      echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  388.      cpp.put_c_file(tmp_file_read);
  389.       end;
  390.  
  391. feature {NONE}
  392.  
  393.    add_directory(path, dir: STRING) is
  394.       require
  395.      path.count > 0;
  396.      dir.count > 0
  397.       do
  398.      if slash_separator then
  399.         path.set_last('/');
  400.         path.append(dir);
  401.         path.set_last('/');
  402.      elseif backslash_separator then
  403.         path.set_last('\');
  404.         path.append(dir);
  405.         path.set_last('\');
  406.      elseif colon_separator then
  407.         path.set_last(':');
  408.         path.append(dir);
  409.         path.set_last(':');
  410.      elseif vms_system = system_name then
  411.         path.set_last(']');
  412.         path.remove_last(1);
  413.         path.set_last('.');
  414.         path.append(dir);
  415.         path.set_last(']');
  416.      end;
  417.       end;
  418.  
  419. feature {NONE}
  420.  
  421.    parent_directory(path: STRING) is
  422.      -- Remove the last sub-directory of `path' (assume `path' is 
  423.      -- a combination of more than one directory). 
  424.       require
  425.      path.count > 0
  426.       do
  427.      if slash_separator then
  428.         from
  429.            path.remove_last(1);
  430.         until
  431.            path.last = '/'
  432.         loop
  433.            path.remove_last(1);
  434.         end;
  435.      elseif backslash_separator then
  436.         from
  437.            path.remove_last(1);
  438.         until
  439.            path.last = '\'
  440.         loop
  441.            path.remove_last(1);
  442.         end;
  443.      elseif colon_separator then
  444.         from
  445.            path.remove_last(1);
  446.         until
  447.            path.last = ':'
  448.         loop
  449.            path.remove_last(1);
  450.         end;
  451.      elseif vms_system = system_name then
  452.         from
  453.            path.remove_last(1);
  454.         until
  455.            path.last = '.'
  456.         loop
  457.            path.remove_last(1);
  458.         end;
  459.         path.remove_last(1);
  460.         path.extend(']');
  461.      end;
  462.       ensure
  463.      path.count > 0;
  464.      path.count < (old path.count)
  465.       end;
  466.  
  467. feature {NONE}
  468.  
  469.    slash_separator: BOOLEAN is
  470.       do
  471.      if unix_system = system_name then
  472.         Result := true;
  473.      elseif amiga_system = system_name then
  474.         Result := true;
  475.      end;
  476.       end;
  477.  
  478. feature {NONE}
  479.  
  480.    backslash_separator: BOOLEAN is
  481.       do
  482.      if windows_system = system_name then
  483.         Result := true;
  484.      elseif dos_system = system_name then
  485.         Result := true;
  486.      elseif os2_system = system_name then
  487.         Result := true;
  488.      end;
  489.       end;
  490.       
  491. feature {NONE}
  492.  
  493.    colon_separator: BOOLEAN is
  494.       do
  495.      if macintosh_system = system_name then
  496.         Result := true;
  497.      elseif beos_system = system_name then
  498.         Result := true;
  499.      end;
  500.       end;
  501.       
  502. feature {SHORT_PRINT}
  503.  
  504.    format_directory(format: STRING): STRING is
  505.       require
  506.      format /= Void
  507.       do
  508.      !!Result.make(sys_directory.count + 10);
  509.      Result.copy(sys_directory);
  510.      parent_directory(Result);
  511.      add_directory(Result,"short");
  512.      add_directory(Result,format);
  513.       end;
  514.  
  515. feature
  516.  
  517.    bad_use_exit(command_name: STRING) is
  518.       require
  519.      command_name /= Void
  520.       do
  521.      echo.w_put_string("Bad use of command `");
  522.      echo.w_put_string(command_name);
  523.      echo.w_put_string("'.%N");
  524.      tmp_path.copy(sys_directory);
  525.      parent_directory(tmp_path);
  526.      add_directory(tmp_path,"man");
  527.      tmp_path.append(command_name);
  528.      tmp_path.append(help_suffix);
  529.      echo.w_put_string("See docmentation in file:%N   ");
  530.      echo.w_put_string(tmp_path);
  531.      echo.w_put_character('%N');
  532.      die_with_code(exit_failure_code);
  533.       end;
  534.  
  535. feature {JVM}
  536.  
  537.    class_file_path(path, directory, class_file_name: STRING) is
  538.      -- Prepare `path' using `directory' and `class_file_name'.
  539.       do
  540.      path.clear;
  541.      if vms_system = system_name then
  542.         if directory.first /= '[' then
  543.            path.extend('[');
  544.         end;
  545.      end;
  546.      path.append(directory);
  547.      if slash_separator then
  548.         path.set_last('/');
  549.      elseif backslash_separator then
  550.         path.set_last('\');
  551.      elseif colon_separator then
  552.         path.set_last(':');
  553.      elseif vms_system = system_name then
  554.         path.set_last(']');
  555.      end;
  556.      path.append(class_file_name);
  557.      path.append(class_suffix);
  558.       end;
  559.  
  560. feature {C_PRETTY_PRINTER}
  561.  
  562.    put_c_main_function_type(out_c: STD_FILE_WRITE) is
  563.       do
  564.      if vms_system = system_name then
  565.         out_c.put_string(fz_void);
  566.      else
  567.         out_c.put_string(fz_int);
  568.      end;
  569.       end;
  570.  
  571. feature {C_PRETTY_PRINTER}
  572.  
  573.    strip_executable(command: STRING): BOOLEAN is
  574.       require
  575.      command /= Void
  576.       do
  577.      if unix_system = system_name then
  578.         Result := true;
  579.         command.copy("strip ");
  580.      elseif os2_system = system_name then
  581.         Result := true;
  582.         command.copy("emxbind -qs ");
  583.      end;     
  584.       end;
  585.       
  586. feature
  587.  
  588.    make_suffix: STRING is
  589.       -- Suffix for make file produced by `compile_to_c'.
  590.       once
  591.      if dos_system = system_name then
  592.         Result := ".BAT";
  593.      elseif windows_system = system_name then
  594.         Result := ".bat";
  595.      elseif vms_system = system_name then
  596.         Result := ".COM";
  597.      elseif os2_system = system_name then
  598.         Result := ".CMD";
  599.      else
  600.         Result := ".make";
  601.      end;
  602.       end;
  603.  
  604. feature 
  605.  
  606.    x_suffix: STRING is 
  607.      -- Executable files suffix.
  608.       once
  609.      if dos_system = system_name or else
  610.         vms_system = system_name
  611.       then
  612.         Result := ".EXE";
  613.      elseif os2_system = system_name then
  614.         Result := ".exe";
  615.      elseif windows_system = system_name then
  616.         Result := ".exe";
  617.      else
  618.         Result := "";
  619.      end;
  620.       end;
  621.  
  622. feature
  623.  
  624.    o_suffix_memory: STRING is 
  625.      -- Object File produced by the C Compiler.
  626.       once
  627.      !!Result.make(4);
  628.      tmp_path.copy(sys_directory);
  629.      tmp_path.append("o_suffix.");
  630.      tmp_path.append(system_name);
  631.      echo.sfr_connect_or_exit(tmp_file_read,tmp_path);
  632.      Result := echo.read_word_in(tmp_file_read);
  633.      tmp_file_read.disconnect;
  634.       end;
  635.  
  636. feature {NONE}
  637.  
  638.    singleton_memory: SYSTEM_TOOLS is
  639.       once
  640.      Result := Current;
  641.       end;
  642.  
  643. invariant
  644.  
  645.    is_real_singleton: Current = singleton_memory
  646.    
  647. end -- SYSTEM_TOOLS
  648.